const { Success, Fail, Custom } = require("../../utils/status");
const { fileWhiter, getFileExtname, fileReadChunk, getContentType } = require("../../utils/utils");
const moment = require("moment");
const uuid = require("uuid");
const fs = require("fs");
const path = require("path");
const { insertFile, getFileById, fileByMd5 } = require("../../service/filelist")
const { insertDownloadFile, getDownloadFileById } = require("../../service/downloadfile")
const { insertDownloadHistory } = require("../../service/downloadhistory")
const trickle = require('trickle');
module.exports = {
    fileCheck: async (ctx) => {//文件校验
        const { body } = ctx.request;
        let { fileMD5, countChunk, fileName } = body
        var send;
        if (fileMD5 && countChunk && fileName) {
            const sendFile = () => {
                var filePath = path.join(process.cwd(), "./temporaryFile/" + fileMD5);
                var file = fs.existsSync(filePath);
                if (file) {
                    let list = fs.readdirSync(filePath);
                    send = new Custom({
                        code: 201,//文件之前传过
                        data: { hasFileList: list },
                        msg: "可以进行断点续传！"
                    });
                } else {
                    send = new Success({
                        msg: "可以进入缓存目录！"
                    });
                }
            }
            var fileData = await fileByMd5(fileMD5);
            if (fileData) {
                var filePath = path.join(process.cwd(), fileData.fileName);
                var file = fs.existsSync(filePath);
                if (file) {
                    var createTime = moment().format("YYYY-MM-DD HH:mm:ss")
                    var newFileData = await insertFile({
                        userId: ctx.state.user.id || 0,
                        md5: fileMD5,
                        oldFileName: fileName,
                        fileName: fileData.fileName,
                        createTime: createTime
                    })
                    var downloadFileData = await insertDownloadFile({
                        userId: ctx.state.user.id || 0,
                        fileListId: newFileData.id,
                        createTime: createTime
                    })
                    send = new Custom({
                        code: 203,//文件之前传过
                        data: downloadFileData.id,
                        msg: "文件上传成功！"
                    });
                } else {
                    sendFile();
                }
            } else {
                sendFile();
            }

        } else {
            send = new Fail({
                msg: "参数传入错误！"
            });
        }
        ctx.body = send
    },
    fileUpload: (ctx) => {
        const { body, files } = ctx.request;
        const { fileMD5, index } = body;
        var send;
        if (fileMD5 && index >= 0 && files.file) {
            var fileRed = fs.readFileSync(files.file.path)
            fileWhiter("/temporaryFile/" + fileMD5, index, fileRed);
            fs.unlinkSync(files.file.path);
            send = new Success({
                msg: "一片存入成功！"
            });
        } else {
            send = new Fail({
                msg: "参数传入错误！"
            });
        }
        ctx.body = send;
    },
    fileUploadMerge: async (ctx) => {
        const { body } = ctx.request;
        const { fileMD5, countChunk, fileName } = body;
        var send;
        if (fileMD5 && countChunk && fileName) {
            var filePath = path.join(process.cwd(), "./temporaryFile/" + fileMD5);
            let list = fs.readdirSync(filePath);
            const time = moment().format("YYYY-MM-DD");
            const extname = getFileExtname(fileName);
            const fileUuid = uuid.v4() + extname;
            const whiterFilePath = "/file/" + time
            if (list.length == countChunk) {
                for (let i = 0; i < list.length; i++) {
                    const element = list[i];
                    const fileBuffer = fs.readFileSync(filePath + "/" + element);
                    if (i == 0) {
                        fileWhiter(whiterFilePath, fileUuid, fileBuffer)
                    } else {
                        var appendPath = path.join(process.cwd(), whiterFilePath + "/" + fileUuid)
                        fs.appendFileSync(appendPath, fileBuffer)
                    }
                    fs.unlinkSync(filePath + "/" + element)
                }
                var createTime = moment().format("YYYY-MM-DD HH:mm:ss")
                var fileData = await insertFile({
                    userId: ctx.state.user.id || 0,
                    md5: fileMD5,
                    oldFileName: fileName,
                    fileName: whiterFilePath + "/" + fileUuid,
                    createTime: createTime
                })
                var downloadFileData = await insertDownloadFile({
                    userId: ctx.state.user.id || 0,
                    fileListId: fileData.id,
                    createTime: createTime
                })
                fs.rmdirSync(filePath);
                send = new Success({
                    data: downloadFileData.id,
                    msg: "文件合并成功！"
                });
            } else {
                fs.rmdirSync(filePath, { recursive: true });
                send = new Custom({
                    code: 201,
                    msg: "文件已损坏请重新上传！"
                });
            }
        } else {
            send = new Fail({
                msg: "参数传入错误！"
            });
        }
        ctx.body = send
    },
    downloadFile_get_id: async (ctx) => {
        const { params } = ctx.request;
        var send;
        if (params.id) {
            var downloadData = await getDownloadFileById(params.id);
            if (downloadData && (!downloadData.expirationTime || (new Date(downloadData.expirationTime).getTime() > new Date().getTime()))) {
                let { fileListId, downloadSpeed, userId } = downloadData;
                var fileData = await getFileById(fileListId);
                if (fileData) {
                    let { fileName } = fileData;
                    var fileSplit = fileName.split("/")
                    var newfileName = fileSplit[fileSplit.length - 1];
                    var pathFile = path.join(process.cwd(), fileName);
                    if (downloadData.downloadFileName) {
                        newfileName = encodeURIComponent(downloadData.downloadFileName) + getFileExtname(newfileName);
                    }
                    ctx.set('Content-disposition', 'attachment; filename=' + newfileName);
                    if (downloadSpeed) {
                        var stream = trickle({
                            limit: Number(downloadSpeed),
                            interval: 1000
                        })
                        // let resHred = fileReadChunk(ctx.headers.range, pathFile);
                        // ctx.status = resHred.code;
                        // ctx.set(resHred.head);
                        // send = fs.createReadStream(pathFile, resHred.code == 200 ? {} : { start: resHred.start, end: resHred.end }).pipe(stream);
                        var fileSize = fs.statSync(pathFile).size;
                        ctx.set('Content-Type', getContentType(pathFile));
                        ctx.set('Content-Length', fileSize);
                        ctx.set('Keep-Alive', "timeout=5");
                        send = fs.createReadStream(pathFile).pipe(stream);
                    } else {
                        let resHred = fileReadChunk(ctx.headers.range, pathFile);
                        ctx.status = resHred.code;
                        ctx.set(resHred.head);
                        send = fs.createReadStream(pathFile, resHred.code == 200 ? {} : { start: resHred.start, end: resHred.end });
                    }
                    await insertDownloadHistory({
                        ip: ctx.ip,
                        userId: downloadData.userId,
                        oldFileName: fileData.oldFileName,
                        downloadFileName: newfileName,
                        downloadFileId: downloadData.id,
                        createTime: moment().format("YYYY-MM-DD HH:mm:ss")
                    })
                } else {
                    send = new Fail({
                        msg: "文件不存在或已过期！"
                    });
                }
            } else {
                send = new Fail({
                    msg: "文件不存在或已过期！"
                });
            }
        } else {
            send = new Fail({
                msg: "参数传入错误！"
            });
        }
        ctx.body = send
    }
}